import json
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_protect
from django.http import Http404, JsonResponse
from django.contrib.auth.decorators import login_required
from notifications.signals import notify

from blog.models import Post
from .models import Comment


@require_POST
@login_required
@csrf_protect
def new_comment(request):
    """处理发布评论的ajax请求"""
    # 前端传来的数据有评论内容(content)和文章ID(post_id)
    comment_data = json.loads(request.body)
    try:
        post = Post.objects.get(slug=comment_data.get('post_slug', ''))
    except (Post.DoesNotExist, Post.MultipleObjectsReturned):
        return JsonResponse({'code': 1})
    else:
        comment = Comment.objects.create(content=comment_data['content'], post_id=post.id, user=request.user)

        parent_comment_slug = comment_data.get('parent_comment_slug')
        # 如果是回复评论
        if parent_comment_slug is not None:
            parent_comment = Comment.objects.get(slug=parent_comment_slug)
            # https://www.jianshu.com/p/09e24579a707
            # 举例说明：一级评论人为a，二级评论人为b（parent为a），三级评论人为c（parent为b）。因为我们不允许评论超过两级，因此将
            # c的parent重置为a，reply_to记录为b，这样就能正确追溯真正的被评论者了。
            # 若回复层级超过二级，则转换为二级
            comment.parent_id = parent_comment.get_root().id
            # 被回复人
            comment.reply_to = parent_comment.user

            # 发送通知
            # actor：发送通知的对象
            # recipient：接收通知的对象
            # verb：动词短语
            # target：链接到动作的对象（可选）
            # action_object：执行通知的对象（可选）
            # 张三(actor)在哪篇文章(target)中对你(recipient)发表了(verb)评论(action_object)

            # 会在notifications_notification表中生成一行数据
            if request.user != parent_comment.user: # 自己回复自己的评论不发通知信息
                notify.send(
                    request.user,  # actor
                    recipient=parent_comment.user,
                    verb='回复了你',
                    target=post,
                    action_object=comment,
                )

        # 更新评论数目
        post.num_comments += 1
        post.save()

        comment.save()
        comment_data = {
            'username': comment.user.username,
            'content': comment.content,
            'date_created': comment.date_created.strftime('%Y.%m.%d %H:%M'),
            'avatar_url': comment.user.profile.avatar.url,
            'comment_slug': comment.slug,
        }
        return JsonResponse({'code': 0, 'data': comment_data}, status=201)  # HTTP 201 CREATED


@require_POST
@login_required
@csrf_protect
def delete_comment(request, **kwargs):
    comment_slug = kwargs.get('slug')
    try:
        comment = Comment.objects.get(slug=comment_slug)
    # 评论slug不存在返回404错误页面
    # TODO:不太合理
    except Comment.DoesNotExist:
        raise Http404
    else:
        # 该slug对应的评论存在
        if request.user == comment.user:
            comment.delete()
            # 更新评论数
            comment.post.num_comments -= 1
            comment.post.save()

            return JsonResponse({'code': 0})
        else:
            # 用户没有权限删除别人的评论，返回403(Forbidden)
            # 留给前端处理
            return JsonResponse({'code': 1}, status=403)
